<?php

namespace Common\Controller;

use Think\Controller;
use Common\Service\DataService;

class BasicAdmin extends Controller {

    /**
     * 页面标题
     * @var string
     */
    public $title;

    /**
     * 默认操作数据表
     * @var string
     */
    public $table;

    public function __construct() {
        parent::__construct();
        $user_info = session('user_info');
        if (!$user_info['id']) {
            $this->redirect('/' . MODULE_NAME . '/login');
        }
//        $name = CONTROLLER_NAME . '/' . ACTION_NAME;
//        if (CONTROLLER_NAME != 'Index' && $user_info['id'] != 10000 && $user_info['id'] != 9999) {
//            $auth = new \Think\Auth();
//            $auth_result = $auth->check($name, $user_info['id']);
//            if ($auth_result === false) {
//                $this->error('没有权限访问!', U('/' . MODULE_NAME));
//            }
//        }
    }

    /**
     * 表单默认操作
     * @param Query $dbQuery 数据库查询对象
     * @param string $tplFile 显示模板名字
     * @param string $pkField 更新主键规则
     * @param array $where 查询规则
     * @param array $extendData 扩展数据
     * @return array|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\Exception
     */
    protected function _form($dbQuery = null, $tplFile = '', $pkField = '', $where = array(), $extendData = array()) {
        $db = is_null($dbQuery) ? M($this->table) : (is_string($dbQuery) ? M($dbQuery) : $dbQuery);
        $pk = empty($pkField) ? ($db->getPk() ? $db->getPk() : 'id') : $pkField;

        $pkValue = I("param.{$pk}", isset($where[$pk]) ? $where[$pk] : (isset($extendData[$pk]) ? $extendData[$pk] : null));
// 非POST请求, 获取数据并显示表单页面
        if (!IS_POST) {
            empty($where) ? $where = array($pk => $pkValue) : $where;
            $vo = ($pkValue !== null) ? array_merge((array) $db->where($where)->find(), $extendData) : $extendData;
            if (false !== $this->_callback('_form_filter', $vo, array())) {
                empty($this->title) || $this->assign('title', $this->title);
                $this->assign('vo', $vo);
                return $this->display($tplFile);
            }
            return $vo;
        }
// POST请求, 数据自动存库
        $data = array_merge(I('post.'), $extendData);
        if (false !== $this->_callback('_form_filter', $data, array())) {
            $result = DataService::save($db, $data, $pk, $where);
            if (false !== $this->_callback('_form_result', $result, $data)) {
                if ($result !== false) {
                    $this->success('恭喜, 数据保存成功!', '');
                }
                $this->error('数据保存失败, 请稍候再试!');
            }
        }
    }

    /**
     * 列表集成处理方法
     * @param Query $dbQuery 数据库查询对象
     * @param bool $isPage 是启用分页
     * @param bool $isDisplay 是否直接输出显示
     * @param bool $total 总记录数
     * @param array $result 结果集
     * @return array|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\Exception
     */
    protected function _list($dbQuery = null, $total = false, $isPage = true, $isDisplay = true, $result = array()) {
        $db = is_null($dbQuery) ? M($this->table) : (is_string($dbQuery) ? M($dbQuery) : $dbQuery);
// 列表排序默认处理
        if (IS_POST && I('post.action') === 'resort') {
            foreach (I('post.') as $key => $value) {
                if (preg_match('/^_\d{1,}$/', $key) && preg_match('/^\d{1,}$/', $value)) {
                    list($where, $update) = array(array('id' => trim($key, '_')), array('sort' => $value));
                    if (false === M($db->getTableName())->where($where)->save($update)) {
                        $this->error('列表排序失败, 请稍候再试');
                    }
                }
            }
            $this->success('列表排序成功, 正在刷新列表');
        }

        if ($isPage && $total) {
            $rows = intval(I('get.rows', cookie('page-rows')));
            cookie('page-rows', $rows = $rows >= 10 ? $rows : 20);
// 分页数据处理
            if (($totalNum = $total) > 0) {
                $query = I('get.', '', 'urlencode');
                $page = new \Think\Page($totalNum, $rows);
                $result = $db->limit($page->firstRow, $rows)->select();
                $p = C('VAR_PAGE') ? C('VAR_PAGE') : 'p';
                list($rowsHTML, $pageHTML, $maxNum) = array(array(), array(), ceil($page->totalRows / $page->listRows));
                foreach (array(10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200) as $num) {
                    list($query['rows'], $query[$p]) = array($num, '1');
                    $url = U('/' . MODULE_NAME) . '#' . strtolower(U()) . '?' . http_build_query($query);
                    $rowsHTML[] = "<option data-url='{$url}' " . ($rows === $num ? 'selected' : '') . " value='{$num}'>{$num}</option>";
                }
                for ($i = 1; $i <= $maxNum; $i++) {
                    list($query['rows'], $query[$p]) = array($rows, $i);
                    $url = U('/' . MODULE_NAME) . '#' . strtolower(U()) . '?' . http_build_query($query);
                    $selected = $i === I("get.{$p}", 1, 'intval') ? 'selected' : '';
                    $pageHTML[] = "<option data-url='{$url}' {$selected} value='{$i}'>{$i}</option>";
                }
                list($pattern, $replacement) = array(array('|href="(.*?)"|', '|pagination|'), array('data-open="$1"', 'pagination pull-right'));
                $html = "<span class='pagination-trigger nowrap'>共 {$totalNum} 条记录，每页显示 <select data-auto-none>" . join('', $rowsHTML) . "</select> 条，共 " . ceil($totalNum / $rows) . " 页当前显示第 <select>" . join('', $pageHTML) . "</select> 页。</span>";

                list($total, $list, $pages) = array($totalNum, $result, $html . preg_replace($pattern, $replacement, strtolower($page->show())));
            } else {
                list($total, $list, $pages) = array($totalNum, $result, '');
            }
        } else {
            $result = $db->select();
        }
        if (false !== $this->_callback('_data_filter', $result, array()) && $isDisplay) {
            !empty($this->title) && $this->assign('title', $this->title);
            $this->assign('list', $result);
            $this->assign('page', $pages);
            $this->assign('star', $page->firstRow);
            return $this->display();
        }
        return $result;
    }

    /**
     * 当前对象回调成员方法
     * @param string $method
     * @param array|bool $data1
     * @param array|bool $data2
     * @return bool
     */
    protected function _callback($method, &$data1, $data2) {
        foreach (array($method, "_" . ACTION_NAME . "{$method}") as $_method) {
            if (method_exists($this, $_method) && false === $this->$_method($data1, $data2)) {
                return false;
            }
        }
        return true;
    }

}
